01|写到最后,真正的问题已经不是某个属性了

前七篇一路写下来,表面上看,主角换了很多次。

有时候是 CSS1

有时候是 CSS 2.1

有时候是 Acid2前缀危机CSS Regions

可如果你退一步看,会发现这整套故事其实一直在重复同一个问题:

为什么有些 CSS 功能,慢归慢,最后还是熬出来了;而另一些,看上去同样性感、同样有需求、甚至连标准文档都有了,却还是死在半路上?

这篇就是收束篇。

不再按年代讲。

而是按命运讲。

把这些年 CSS 世界里最典型的几类案例摆在一起,看看它们最后到底是怎么活下来的,又是怎么死掉的。


02|第一类:需求真、路径清、虽然慢,但能熬出来

这类能力的共同特点是:

  • 需求长期真实存在
  • 不只是某一家公司在喊
  • 浏览器团队虽然嫌麻烦,但不觉得它违背平台方向
  • 规范可以反复打磨,最后能落到比较稳定的实现上

最典型的一个,就是 CSS Grid

Grid 的第一份公开工作草案是 2011 年 4 月 7 日。它最早就带着很明显的“我要解决真正布局问题”的气质。不是加点炫技特效,而是认真处理页面大区块、二维布局、区域划分这些老大难。

它走得一点也不快。2011 出草案,后面一路改、一路磨,到 2017 年 才进入比较像样的 Candidate Recommendation 阶段。

可它最后还是成了。

为什么?

因为 Grid 虽然难,但它解决的问题太真了。

前端用 float、表格、绝对定位、再到 Flexbox,绕了好多年,始终在等一个更像“真正布局系统”的东西。Grid 一旦成形,大家几乎立刻明白:这不是锦上添花,这是终于有了像样工具。

也就是说,Grid 这条线虽然慢,却属于那种很典型的“平台迟早得给”的能力。

它不靠一家公司硬推。

它靠的是:

整个行业迟早都会走到这里。


03|第二类:大家都想要,但浏览器长期觉得“做不起”

这里的代表,是 :has()container queries

它们最有意思的地方,在于:

开发者想要,想了很多年;

规范也不是没想过;

可浏览器团队一直卡在一句话上:

“这玩意儿理论上很美,但性能上你让我怎么活?”

先说 :has()

今天你已经能把它当“父选择器终于来了”来庆祝,可这东西在 CSS 世界里几乎是执念级愿望。WebKit 自己后来都承认:这事讨论了二十多年。

难点不是语法。

语法谁都能写。

难点是:浏览器如果真允许你“根据子元素状态去反过来选父元素”,面对复杂 DOM、大量状态变化时,性能会不会直接炸掉?

所以 `:has()`` 被拖了特别久。早期版本甚至一度被放进 CSS3 讨论里,后来又被推迟。直到 Safari 15.4 在 2022 年 3 月 落地,WebKit 才算真的证明:这东西不是做不到,而是要先把优化方案想清楚。同年 Chrome 105 也跟上。

这类能力最典型的命运就是:

不是没人想做。

而是所有人都得先等某个团队出来证明:

“别怕,跑得动。”

container queries 更典型。

它几乎是组件化时代前端最著名的“圣杯需求”之一。大家想了很多年,甚至很多人一度把它当 Web 平台“明明就该有却迟迟不给”的代表。

可 CSS 工作组和实现者多年都在说一件事:

这问题接近“不可能”。

为什么?

因为如果子元素的样式根据容器尺寸变,容器尺寸又会被子元素影响,那你很容易就写出一个无限循环:我因为你变,你因为我变,大家一起没完没了。

这也是为什么 Containment API 后来会变得关键。它不是为了煽情,它是拿来切断这种循环依赖的。等到约束条件终于更清楚,container queries 才在 2022 年开始真正大规模落地:Chrome/Edge 105、Safari 16,Firefox 110 随后跟上。

所以 :has()container queries 这类功能的规律其实很明确:

不是需求不够强,而是浏览器先得活下来。

只要实现代价还像天坑,它们就会在“大家都知道很需要”和“谁也不敢先发货”之间悬很多年。


04|第三类:看起来很美,但和主流引擎的路线不顺路

这类案例最典型的,就是上一篇写过的 CSS Regions

它不是没有需求。

也不是没有文档。

更不是没人实现。

它的问题在于:它解决的那类“精致排版”需求,并没有重要到让所有主流引擎都愿意为它长期交性能和复杂度的账。

这就是它和 Grid 最大的不同。

Grid 解决的是几乎每个 Web 项目都会撞上的布局难题。

Regions 解决的,则更像是一类特定出版和设计场景的高级诉求。

不是没价值。

但没价值到让 Blink 这种把移动性能放在头号位置的引擎说:

“好,我愿意背这 1 万多行、140 多个文件散落的复杂度,长期陪你养。”

你会发现,很多“死在半路上的 CSS”,未必是因为它们差。

而是因为它们没有足够大、足够普遍、足够符合主流平台方向的需求,去压过自己的成本。

标准化世界很现实。

你不能只证明一项能力“有趣”。

你得证明它:

  • 足够多人需要
  • 足够多场景会反复用
  • 足够多浏览器觉得值得维护

只要这三条里少掉两条,它就很容易变成纸上标准。


05|第四类:不是做成一项功能,而是改造整套权力关系

这个类别,讲的是 Houdini

它很特别,因为它不是在说:

“请给我一个新属性。”

它在说:

“你们浏览器内部那些本来不让作者碰的能力,能不能放一点接口出来?”

Houdini 这条线,代表的是一种完全不同的思路。

前面的大多数 CSS 能力,本质上都是工作组和浏览器厂商协商,最后给开发者一个已经包装好的成品。比如 Grid、:has()、container queries,都是“平台帮你做好,你来用”。

Houdini 想做的,却更像:

“平台先把工具箱打开一角,你自己来扩展。”

比如 @property 这种带类型、默认值、继承控制的自定义属性;再比如 Paint API / worklet 这种让你能往 CSS 的绘制阶段插手的能力。

这条路线为什么重要?

因为它说明 CSS 世界开始承认:有些需求,未必适合等工作组慢慢把成品做出来。与其每次都围着“能不能给我一个新特性”打转,不如想办法让开发者能在一定边界内自己补一点。

但 Houdini 的命运也提醒你另一件事:

暴露底层能力,不等于大家都会马上跟。

它很有想象力,也很能代表平台开放的一种新方向,可它的支持情况、使用门槛、心智成本,始终让它更像“高级武器库”,而不是所有前端今天就会天天拿的主力兵器。

所以 Houdini 这一类功能的活法,和前面几类又不一样:

它不是靠“人人都急着要”活下来;

也不是靠“解决一个超大共性痛点”活下来;

它更像是在为未来铺一条路,看平台愿不愿意把更多权力交出来。


06|写到这里,可以总结出一条很土但很准的规律

什么样的 CSS 更容易活下来?

通常满足这几个条件:

  1. 问题足够普遍
  2. 收益足够大
  3. 实现代价虽然高,但还能被主流引擎接受
  4. 不会明显违背浏览器当前最重视的平台方向

反过来,什么样的 CSS 容易在半路掉队?

也有几个共性:

  1. 需求更偏垂直场景
  2. 复杂度分散又顽固
  3. 性能账算不过来
  4. 只有提案方特别热情,主流实现方并不想长期养

你把这个模板套回前几篇,几乎篇篇都说得通。

  • CSS1 / CSS 2.1 活下来,是因为平台离不开它
  • Grid 活下来,是因为布局痛点太大
  • :has() / container queries 熬出来,是因为需求真到不可能一直装看不见,最后又终于有人把性能问题啃下来了
  • Regions 半路失速,是因为它的价值没有大到足以覆盖实现成本
  • 前缀危机 会爆,是因为“实验机制”被市场份额挟持了
  • Houdini 则像一条旁支路线,告诉你平台也在尝试换一种交权方式

说到底,CSS 从来不是“设计师想要什么,标准就给什么”的许愿池。

它更像一张反复拉扯的账单。

想象力是一列。

复杂度是一列。

性能是一列。

维护成本是一列。

生态收益是一列。

最后能不能活下来,看的不是谁喊得最响,而是谁在总账上算得过去。


07|所以,CSS 江湖讲到最后,其实是一个“现实如何驯服理想”的故事

很多人把 CSS 看成一门“写写样式”的语言。

这当然没错。

但如果你把它放到三十年的标准史里看,它其实更像一个不断被现实拧来拧去的实验场。

这里面有理想主义。

有工程保守主义。

有市场份额带来的傲慢。

有工具链和教程把半成品写成常识的荒诞。

也有那种很笨、很慢、但最后真的把难题啃下来的耐心。

所以这组文章如果要收在一句话里,我大概会这么说:

CSS 从来不是一门只靠语法成长起来的语言。它每长出一根新枝条,背后都有人在吵:这东西值不值、跑不跑得动、会不会把平台拖垮。

这才是它真正的江湖味。

不是炫技。

而是每一个看起来理所当然的能力,背后都有人替你把账吵清楚了。


如果你只记一句,那就记这句:

能熬成标准的 CSS,不只是“被人喜欢”的 CSS,更是“被浏览器、规范和现实同时勉强接受”的 CSS。


编者注(事实核对)CSS Grid 首份公开工作草案为 2011-04-07,后在 2017 进入 Candidate Recommendation 阶段;可由 W3C publication history 与首份 WD 互证。:has() 长期因性能顾虑被推迟,WebKit 在 2022-03(Safari 15.4)率先发布、Chromium 在 2022-08(Chrome 105)跟进,这一叙述可由 WebKit 与 Chrome 开发博客互证。container queries 长期被视为难解问题,后依赖 containment 思路逐步落地,Chrome/Edge 105、Safari 16、Firefox 110 为主要实现节点。Houdini 作为一组向开发者暴露 CSS 引擎部分能力的 API,可由 MDN、W3C drafts、Chrome 开发文档核对。文中将这些功能分为“熬出来”“死在半路”“改造权力关系”等类别,属于写作性归纳,不是 W3C 官方分类。


关键人物速览

  • Rachel Andrew:CSS Grid 最重要的布道者之一。第八篇提到 Grid 能“熬出来”,很大一部分也因为有人持续把它讲给开发者听、用给开发者看。
  • Jen Simmons:另一位让 Grid、:has() 等能力更快进入大众前端视野的关键传播者。她常常把“复杂标准”翻译成开发者听得懂的语言。
  • Miriam Suzanne:container queries 这条线上绕不开的人物之一。很多关于“为什么它曾经被认为不可能”的解释,后来都和她的工作与表达有关。
  • Tab Atkins Jr.:贯穿多条现代 CSS 模块路线的重要编辑。无论是 Grid、容器查询,还是整体模块推进,后期都离不开他这条工作线。
  • Elika Etemad(fantasai):长期参与现代 CSS 模块化与规范推进的重要编辑。第八篇这种“总账视角”,其实很像她一贯在工作组里做的事:把散乱的需求整理成能落地的路线。

参考与延伸阅读

  1. CSS Grid Layout Module Level 1 publication history
    https://w3.org/standards/history/css-grid-1

  2. Grid Layout(First Public Working Draft, 2011-04-07)
    https://www.w3.org/TR/2011/WD-css3-grid-layout-20110407

  3. WebKit:Using :has() as a CSS Parent Selector and much more
    https://webkit.org/blog/13096/css-has-pseudo-class/

  4. Chrome Developers::has() in Chrome 105
    https://developer.chrome.com/blog/has-m105/

  5. MDN:CSS container queries
    https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Containment/Container_queries

  6. W3C:CSS Containment Module Level 3
    https://www.w3.org/TR/css-contain-3/

  7. MDN:CSS Houdini
    http://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Properties_and_values_API/Houdini

  8. W3C Drafts:CSS Painting API Level 1
    https://drafts.css-houdini.org/css-paint-api

  9. web.dev:Cross-browser paint worklets and Houdini.how
    https://web.dev/articles/houdini-how

  10. W3C / Bert Bos:‘CSS X’
    https://www.w3.org/blog/2020/css-x/


系列完。若继续写番外篇,最适合开的三条线是:Grid 的逆袭、:has() 二十年难产史、以及 container queries 为什么曾被说成“不可能”。